/*
 * GraphQL对象类型 - 人员部件GraphQL对象类型
 * 
 * 主要功能：
 * - 为PersonPart定义GraphQL对象类型
 * - 映射人员部件的属性到GraphQL字段
 * - 支持复杂类型的GraphQL查询
 * - 提供类型安全的GraphQL接口
 */

using GraphQL.Types;
using Lombiq.TrainingDemo.Models;

namespace Lombiq.TrainingDemo.GraphQL.Services;

/// <summary>
/// 人员部件GraphQL对象类型 - 为PersonPart定义GraphQL对象类型
/// 
/// 主要用途：
/// - 为PersonPart定义GraphQL对象类型
 //* - 映射人员部件的属性到GraphQL字段
 //* - 支持复杂类型的GraphQL查询
 //* - 提供类型安全的GraphQL接口
 //* 
 //* 使用场景：
/// - 在GraphQL查询中访问人员信息
/// - 支持人员数据的类型安全查询
/// - 提供人员部件的完整GraphQL接口
/// - 实现复杂类型的GraphQL映射
/// 
/// 设计原因：
/// - 为内容部件提供GraphQL支持
/// - 实现类型安全的GraphQL查询
/// - 提供统一的GraphQL接口定义
/// - 支持复杂数据类型的映射
/// 
/// 设计模式：
/// - 继承模式：继承ObjectGraphType<T>实现对象类型
/// - 字段映射模式：使用Field方法映射属性
/// - 描述模式：为字段提供描述信息
/// - 解析模式：使用Resolve方法处理复杂逻辑
/// </summary>
// 我们为内容部件添加一个模型到GraphQL schema。内容类型由Orchard Core自动添加。
public sealed class PersonPartObjectGraphType : ObjectGraphType<PersonPart>
{
    /// <summary>
    /// 出生日期描述 - 用于GraphQL字段描述
    /// 
    /// 功能说明：
    /// - 在索引中有对应的字段
    /// - 应与PersonPartWhereInputObjectGraphType中的描述保持一致
    /// - 避免重复定义描述文本
    /// </summary>
    internal const string BirthDateDescription = "The person's date of birth, if any.";

    /// <summary>
    /// 惯用手描述 - 用于GraphQL字段描述
    /// 
    /// 功能说明：
    /// - 在索引中有对应的字段
    /// - 应与PersonPartWhereInputObjectGraphType中的描述保持一致
    /// - 避免重复定义描述文本
    /// </summary>
    internal const string HandednessDescription = "The person's dominant hand.";

    /// <summary>
    /// 构造函数 - 定义PersonPart的GraphQL字段
    /// 
    /// 功能说明：
    /// - 映射PersonPart的属性到GraphQL字段
    /// - 设置字段的可空性和描述
    /// - 处理复杂类型的字段映射
    /// - 支持枚举类型的字段定义
    /// 
    /// 字段映射：
    /// - Name：人员姓名
    /// - BirthDateUtc：出生日期
    /// - Biography：个人传记（复杂类型）
    /// - Handedness：惯用手（枚举类型）
    /// </summary>
    public PersonPartObjectGraphType()
    {
        // 通常允许空值是好的。但是，这些简单字段默认不启用空值，所以确保将nullable参数设置为true。
        Field(part => part.Name, nullable: true).Description("The person's name.");
        Field(part => part.BirthDateUtc, nullable: true).Description(BirthDateDescription);

        // 您也可以返回计算类型，当您的属性不是原始类型时。实际上这个不是必需的，
        // 因为Orchard Core也会自动为您的内容字段在内容项上创建字段。但这是一个很好的例子，
        // 说明如何在复杂类型中深入挖掘以直接暴露其成员。

        // 注意nameof：GraphQL.Net自动将字段和参数转换为schema中的camelCase。
        // 但是如果您需要比较或查找名称，请使用name.toCamelCase()扩展方法以避免难以诊断的错误。
        Field<StringGraphType>(nameof(PersonPart.Biography))
            .Description("This is the person's life story.")
            .Resolve(context => context.Source.Biography.Text);

        // 您必须为枚举添加单独的GraphQL类型，以便它们转换为GraphQL枚举类型。这样，
        // 它们将作为UPPERCASE文本返回，而不是它们的整数表示。在继续之前，查看
        // GraphQL/Models/HandednessEnumerationGraphType.cs文件以了解这是如何完成的。

        // 注意：此类型在使用时被明确引用，您不必将其添加到依赖注入服务集合中。
        Field<HandednessEnumerationGraphType>(nameof(PersonPart.Handedness))
            .Description(HandednessDescription)
            .Resolve(context => context.Source.Handedness);
    }
}

// 下一站：Services/PersonPartWhereInputObjectGraphType.cs
